package com.ruoyi.base.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.base.domain.vo.SyYjDetailVo;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.utils.TreeBuildUtils;
import com.ruoyi.sycs.domain.BsJudgeBase;
import com.ruoyi.sycs.domain.SycsDataDetail;
import com.ruoyi.sycs.domain.bo.BsJudgeBaseBo;
import com.ruoyi.sycs.domain.vo.BsJudgeBaseVo;
import com.ruoyi.sycs.service.IBsJudgeBaseService;
import com.ruoyi.sycs.service.ISycsDataDetailService;
import com.ruoyi.sycs.service.ISycsDataDetailSyService;
import com.ruoyi.sycs.service.ISycsDataDetailWaterService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.base.domain.bo.SyTypeBo;
import com.ruoyi.base.domain.vo.SyTypeVo;
import com.ruoyi.base.domain.SyType;
import com.ruoyi.base.mapper.SyTypeMapper;
import com.ruoyi.base.service.ISyTypeService;

import java.util.*;

/**
 * 试验类型Service业务层处理
 *
 * @author zyb
 * @date 2024-04-09
 */
@RequiredArgsConstructor
@Service
public class SyTypeServiceImpl implements ISyTypeService {

    private final SyTypeMapper baseMapper;
    private final ISycsDataDetailService iSycsDataDetailService;
    private final ISycsDataDetailSyService iSycsDataDetailSyService;
    private final ISycsDataDetailWaterService iSycsDataDetailWaterService;
    private final IBsJudgeBaseService iBsJudgeBaseService;
    /**
     * 查询试验类型
     */
    @Override
    public SyTypeVo queryById(Long syTypeId){
        return baseMapper.selectVoById(syTypeId);
    }


    /**
     * 查询试验类型列表
     */
    @Override
    public List<SyTypeVo> queryList(SyTypeBo bo) {
        LambdaQueryWrapper<SyType> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<SyType> buildQueryWrapper(SyTypeBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<SyType> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getParentId() != null, SyType::getParentId, bo.getParentId());
        lqw.eq(bo.getLevel() != null, SyType::getLevel, bo.getLevel());
        lqw.like(StringUtils.isNotBlank(bo.getSyTypeName()), SyType::getSyTypeName, bo.getSyTypeName());
        lqw.eq(StringUtils.isNotBlank(bo.getAncestors()), SyType::getAncestors, bo.getAncestors());
        lqw.eq(StringUtils.isNotBlank(bo.getInnerFlag()), SyType::getInnerFlag, bo.getInnerFlag());
        lqw.eq(bo.getSyBigType() != null, SyType::getSyBigType, bo.getSyBigType());
        lqw.orderByAsc(SyType::getSort);
        return lqw;
    }

    /**
     * 新增试验类型
     */
    @Override
    public Boolean insertByBo(SyTypeBo bo) {
        SyType add = BeanUtil.toBean(bo, SyType.class);
        validEntityBeforeSave(add);
        long parentId = bo.getParentId();
        if (parentId == 0) {
            add.setLevel(1);
        } else {
            SyTypeVo syTypeVo = baseMapper.selectVoById(parentId);
            add.setLevel(syTypeVo.getLevel() + 1);
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setSyTypeId(add.getSyTypeId());
        }
        return flag;
    }

    /**
     * 修改试验类型
     */
    @Override
    public Boolean updateByBo(SyTypeBo bo) {
        SyType update = BeanUtil.toBean(bo, SyType.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(SyType entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除试验类型
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 查询试验类型树结构信息
     *
     * @param type 试验类型信息
     * @return 试验类型树信息集合
     */
    @Override
    public List<Tree<Long>> selectTypeTreeList(SyType type) {
        List<SyType> types = this.selectTypeList(type);
        return buildTypeTreeSelect(types);
    }

    @Override
    public Map listBySyTypeId(SyTypeBo bo, PageQuery pageQuery) {
        Map map = new HashMap();
        // 如果syTypeId为空,则返回空列表
        if (ObjectUtils.isEmpty(bo.getSyTypeId())) {
            map.put("level", 0);
            map.put("type", "DETAIL");
            map.put("page", new Page());
            return map;
        }
        SyType data = baseMapper.selectById(bo.getSyTypeId());
        map.put("type", data.getType());
        map.put("level", data.getLevel());
        switch (data.getType()) {
            case "DETAIL_WATER":
                map.put("page", iSycsDataDetailWaterService.listBySyTypeId(bo.getSyTypeId(), pageQuery));
                return map;
            case "DETAIL_SY":
                map.put("page", iSycsDataDetailSyService.listBySyTypeId(bo.getSyTypeId(), pageQuery));
                return map;
            default:
                if (data.getLevel() != 3) {
                    // 根据parentId 查询子集列表
                    QueryWrapper wrapper = new QueryWrapper();
                    wrapper.eq("del_flag", "0");
                    wrapper.eq("parent_id", bo.getSyTypeId());
                    Page page = baseMapper.selectPage(pageQuery.build(), wrapper);
                    map.put("page", page);
                } else {
                    map.put("page", iSycsDataDetailService.listBySyTypeId(bo.getSyTypeId(), pageQuery));
                }
                return map;
        }
    }

    /**
     * 查询试验类型子集
     *
     * @param bo
     * @return
     */
    @Override
    public TableDataInfo<SyTypeVo> pageSub(SyTypeBo bo, PageQuery pageQuery) {
        if (ObjectUtils.isEmpty(bo.getParentId())) {
            return TableDataInfo.build(new Page<>());
        }
        // 查询子集
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("del_flag", "0");
        wrapper.eq("parent_id", bo.getParentId());
        wrapper.orderByAsc("create_time");
        Page page = baseMapper.selectPage(pageQuery.build(), wrapper);
        // 没有子集查询明细
        if (ObjectUtils.isNotEmpty(page) && CollectionUtils.isEmpty(page.getRecords())) {
            BsJudgeBaseBo judgeBaseBo = new BsJudgeBaseBo();
            judgeBaseBo.setSyType(bo.getParentId().toString());
            Page<BsJudgeBase> basePage = iBsJudgeBaseService.pageBySyType(judgeBaseBo, pageQuery);
            Page subPage = new Page();
            List subRecords = new ArrayList();
            if (ObjectUtils.isNotEmpty(basePage.getRecords())) {
                List<BsJudgeBase> records = basePage.getRecords();
                for (BsJudgeBase record : records) {
                    SyTypeVo entity = new SyTypeVo();
                    entity.setParentId(bo.getParentId());
                    entity.setSyTypeId(Long.valueOf(record.getSyType()));
                    entity.setSyTypeName(record.getJudgeName());
                    entity.setType("detail"); // 标识明细对应数据
                    subRecords.add(entity);
                }
                subPage.setRecords(subRecords);
            }
            return TableDataInfo.build(subPage);
        } else {
            return TableDataInfo.build(page);
        }

    }

    /**
     * 获取试验类型树
     *
     * @param type
     * @return
     */
    @Override
    public List<Tree<Long>> syTpyeTreeBig(SyType type) {
        LambdaQueryWrapper<SyType> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SyType::getDelFlag, "0")
            .eq(ObjectUtil.isNotNull(type.getSyTypeId()), SyType::getSyTypeId, type.getSyTypeId())
            .eq(ObjectUtil.isNotNull(type.getParentId()), SyType::getParentId, type.getParentId())
            .eq(StringUtils.isNotBlank(type.getInnerFlag()), SyType::getInnerFlag, type.getInnerFlag())
            .like(StringUtils.isNotBlank(type.getSyTypeName()), SyType::getSyTypeName, type.getSyTypeName())
            .in(SyType::getLevel, 1, 2)
            .orderByAsc(ObjectUtils.isNotEmpty(type.getCreateTime()), SyType::getCreateTime);
        List<SyType> types = baseMapper.selectList(lqw);
        return buildTypeTreeSelect(types);
    }

    public List<SyType> selectTypeList(SyType type) {
        LambdaQueryWrapper<SyType> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SyType::getDelFlag, "0")
            .eq(ObjectUtil.isNotNull(type.getSyTypeId()), SyType::getSyTypeId, type.getSyTypeId())
            .eq(ObjectUtil.isNotNull(type.getParentId()), SyType::getParentId, type.getParentId())
            .eq(ObjectUtil.isNotNull(type.getInnerFlag()), SyType::getInnerFlag, type.getInnerFlag())
            .like(StringUtils.isNotBlank(type.getSyTypeName()), SyType::getSyTypeName, type.getSyTypeName())
            .le(ObjUtil.isNotNull(type.getLevel()), SyType::getLevel, type.getLevel()) // <= level
            .orderByAsc(ObjectUtils.isNotEmpty(type.getSort()), SyType::getSort);
        return baseMapper.selectList(lqw);
    }

    public List<Tree<Long>> buildTypeTreeSelect(List<SyType> types) {
        if (CollUtil.isEmpty(types)) {
            return CollUtil.newArrayList();
        }
        return TreeBuildUtils.build(types, (type, tree) ->
            tree.setId(type.getSyTypeId())
                .setParentId(type.getParentId())
                .setName(type.getSyTypeName())
                .setWeight(type.getSort())
                .putExtra("level", type.getLevel()));
    }

}
